/*
 * A class that handles messages between clients and server.
 * the "ans" version of eaxh command is the server side.
 * Each calles method will communicate with the "other side", 
 * and will write data to the connection.
 */

#ifndef MESSAGEHANDLER_H
#define MESSAGEHANDLER_H
#include "protocol.h"
#include "protocolexception.h"
#include "connection.h"
#include <string>
#include <map>
#include <vector>
#include <utility>

using namespace std;
namespace client_server {
	class MessageHandler{
		public:
			MessageHandler();
			~MessageHandler();
			
			void ans_list_groups(Connection *conn, vector<pair<unsigned int, string> > v)
				throw(ConnectionClosedException, ProtocolException);
			vector<pair<unsigned int, string> > list_groups(Connection *conn) 
				throw(ConnectionClosedException, ProtocolException);
			
			void ans_create_group(Connection *conn, bool created)
				throw(ConnectionClosedException, ProtocolException); //server side
			int create_group(Connection *conn, string &name)
				throw(ConnectionClosedException, ProtocolException); //client side
			
			void ans_delete_group(Connection *conn, bool removed)
				throw(ConnectionClosedException, ProtocolException); //server side
			bool delete_group(Connection *conn, unsigned int id)
				throw(ConnectionClosedException, ProtocolException); //client side
			
			void ans_list_art(Connection *conn, vector <pair<unsigned int, string> > v)
				throw(ConnectionClosedException, ProtocolException); //server side
			vector<pair<unsigned int, string> > list_art(Connection *conn, unsigned int id)
				throw(ConnectionClosedException, ProtocolException); //client side
			
			void ans_create_art(Connection *conn, bool created); //server side
			int create_art(Connection *conn, unsigned int id,
				string title, string author, string text) throw(ConnectionClosedException, ProtocolException); //client side
			
			void ans_delete_art(Connection *conn, int status)throw(ConnectionClosedException, ProtocolException); //server side
			
			//0 is ok, 1 ng no exist, 2 art no exist .
			int delete_art(Connection *conn, unsigned int g_id, 
				unsigned int a_id)throw(ConnectionClosedException, ProtocolException); //client side
			
			void ans_get_art(Connection *conn, pair<int, map<string, string> > article)
				throw(ConnectionClosedException, ProtocolException); //server side
			pair<int, map<string, string> > get_art(Connection *conn, unsigned int g_id, 
				unsigned int a_id) throw(ConnectionClosedException, ProtocolException); //client side
			
			//Identifies commands from client -> server, returns the command
			// type so that the server can act accordingly and send the rigths ANS and data and stuff..
			char identify(Connection *conn) throw(ConnectionClosedException, ProtocolException);

 			void write_uint(Connection *conn, unsigned int i) throw(ConnectionClosedException);
 			unsigned int read_uint(Connection *conn) throw(ConnectionClosedException, ProtocolException);

 			string read_string(Connection *conn) throw(ConnectionClosedException, ProtocolException);
 			void write_string(Connection *conn, string s) throw(ConnectionClosedException, ProtocolException);
			
		private:
		
		 	void write_code(Connection *conn, char i) throw(ConnectionClosedException);
 			char read_code(Connection *conn) throw(ConnectionClosedException);

 			protocol::Protocol p;


 			void check_code(string fcn, char ref, char rec) throw(ProtocolException);
	};
}

#endif
